/**
 * Copyright 2015 jianglibo@gmail.com
 *
 */
package com.m3958.logcollector.tree;

import java.util.concurrent.ExecutionException;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.m3958.logcollector.exception.CacheLoadMissingException;

/**
 * @author jianglibo@gmail.com
 *         2016年1月12日
 *
 */
public class TreeAssistant<T> {

    private LoadingCache<Long, TreeNode<T>> nodes;

    private Tree<T> tree;

    public TreeAssistant(Tree<T> tree) {
        this.tree = tree;
        createCache();
    }
    
    public TreeNode<T> findById(long id) {
        try {
            return nodes.get(id);
        } catch (ExecutionException e) {
        }
        return null;
    }

    private TreeNode<T> findByIdInternal(long id) {
        return findByIdInternal(tree.getRoot(), id);
    }

    private TreeNode<T> findByIdInternal(TreeNode<T> tn, long id) {
        if (tn.getId() != id) {
            return tn.getChildren().stream().filter(it -> findByIdInternal(it, id) != null).findAny().orElse(null);
        } else {
            return tn;
        }
    }

    private void createCache() {
        nodes = CacheBuilder.newBuilder()//
                .build(new CacheLoader<Long, TreeNode<T>>() {
                    public TreeNode<T> load(Long key) throws CacheLoadMissingException {
                        TreeNode<T> tn = findByIdInternal(key);
                        if (tn == null) {
                            throw new CacheLoadMissingException();
                        }
                        return tn;

                    }
                });
    }

    public void removeCache(long id) {
        nodes.invalidate(id);
    }
}
